In this recipe, we look at reading the value from a button. This will allow you to turn things on and off, and lots more!
This illustrates the key concept of reading digital inputs on the Arduino.
You will need:
Wire up the circuit as follows:
Copy the code below and overwrite the code in the Arduino IDE.
// Constants const int BUTTONPIN = 7; void setup() { // Tell Arduino which pins are input and output pinMode(BUTTONPIN, INPUT); pinMode(LED_BUILTIN, OUTPUT); // Set initial LED state digitalWrite(LED_BUILTIN, LOW); } void loop() { // Read the state of the switch into a local variable int reading = digitalRead(BUTTONPIN); // Set the LED on or off according to the state digitalWrite(LED_BUILTIN, reading); }
Now upload the code to the Arduino.
The LED should start flashing.
The constant BUTTONPIN
is the Arduino pin which we will use to read the button value.
In the setup() function, we need to tell the Arduino that we will be receiving inputs on this pin:
pinMode(BUTTONPIN, INPUT);
In the loop, we create a variable which will receive the value we read from the button pin. This will either be HIGH to indicate that the button is being pressed, or LOW to indicate that the button is not being pressed. We read the value from the pin into this variable:
int reading = digitalRead(BUTTONPIN);
Next, we set the LED to match the value of the reading:
digitalWrite(LED_BUILTIN, reading);
What if we want a toggle button? This will allow us to switch the LED on and off without having to hold the button down. Here are some code changes to do that:
// Constants const int BUTTONPIN = 7; // Variables int ledState = HIGH; // the current state of the LED pin void setup() { // Tell Arduino which pins are input and output pinMode(BUTTONPIN, INPUT); pinMode(LED_BUILTIN, OUTPUT); // Set initial LED state digitalWrite(LED_BUILTIN, ledState); } void loop() { // Read the state of the switch into a local variable: int reading = digitalRead(BUTTONPIN); // If the switch is pressed, flip the state if (reading == HIGH) ledState = !ledState; // Set the LED on or off according to the state digitalWrite(LED_BUILTIN, ledState); }
In this code we create a global variable to record the current led state (on or off, represented by 1 or 0):
int ledState = HIGH;
When we see that the button is pressed, we flip the state.
if (reading == HIGH) ledState = !ledState;
Now we just need to set the LED based on the value of the state variable:
digitalWrite(LED_BUILTIN, ledState);
Here is a short video of it working. But it's not perfect. See the next extension for some improvements.
When you run the toggle button code, you may find that you sometimes press the button and it doesn't seem to change the LED, or it changes and quickly changes back. What you are experiencing is a phenomenon called bounce.
When you press the button, what you are actually doing is making a physical connection between two pieces of metal. At the microscopic level, the moment the physical connection is made is not clear cut, with the connection being made and broken as the two pieces of metal come together. The Arduino takes readings so fast (millions of times per second) that in the course of you pressing the button, it records lots of state changes. The solution is to read values until a a certain time period elapses. If the reading remains the same after that period, we presume the reading is a solid reading. The following code originated from here.
// Constants const int BUTTONPIN = 7; // Variables int ledState = HIGH; // the current state of the LED pin int buttonState; // the current reading from the button pin int lastButtonState = LOW; // the previous reading from the button pin // The following variables are unsigned longs because the time, measured in // milliseconds, will quickly become a bigger number than can be stored in an int. unsigned long lastDebounceTime = 0; // the last time the output pin was toggled unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers void setup() { pinMode(BUTTONPIN, INPUT); pinMode(LED_BUILTIN, OUTPUT); // Set initial LED state digitalWrite(LED_BUILTIN, ledState); } void loop() { // Read the state of the switch into a local variable: int reading = digitalRead(BUTTONPIN); // Check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited long enough // since the last press to ignore any noise // If the switch changed, due to noise or pressing if (reading != lastButtonState) { // Reset the debouncing timer lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { // Whatever the reading is at, it's been there for longer than the debounce // delay, so take it as the actual current state // If the button state has changed if (reading != buttonState) { buttonState = reading; // Only toggle the LED if the new button state is HIGH if (buttonState == HIGH) { ledState = !ledState; } } } // Set the LED on or off according to the state digitalWrite(LED_BUILTIN, ledState); // Save the reading. Next time through the loop, it'll be the lastButtonState lastButtonState = reading; }
Here is a short video of it working.